from utils import log_info, log_exception, log_error
from typing import List, Optional
from .base_dao import BaseDAO
from models.practice_progress import PracticeProgress


class PracticeProgressDAO(BaseDAO[PracticeProgress]):
    """练习进度表数据访问对象"""

    def __init__(self):
        """
        初始化PracticeProgressDAO
        """
        super().__init__(PracticeProgress)

    def _get_table_name(self) -> str:
        """获取表名"""
        return "practice_progress"

    def _get_primary_key(self) -> str:
        """获取主键名"""
        return "id"

    def get_by_user_and_category(self, user_id: int, category: str) -> Optional[PracticeProgress]:
        """
        根据用户ID和分类获取练习进度
        :param user_id: 用户ID
        :param category: 题目分类
        :return: 练习进度实体，如果不存在返回None
        """
        sql = "SELECT * FROM practice_progress WHERE user_id = ? AND category = ?"
        params = (user_id, category)
        return self._execute_query(sql, params, single_result=True)

    def get_all_by_user(self, user_id: int) -> List[PracticeProgress]:
        """
        获取用户的所有练习进度
        :param user_id: 用户ID
        :return: 练习进度实体列表
        """
        sql = "SELECT * FROM practice_progress WHERE user_id = ?"
        params = (user_id,)
        return self._execute_query(sql, params)



    def update_by_user_and_category(self, user_id: int, category: str, **kwargs) -> bool:
        """
        根据用户ID和分类更新练习进度
        :param user_id: 用户ID
        :param category: 题目分类
        :param kwargs: 要更新的字段和值
        :return: 更新成功返回True，否则返回False
        """
        if not kwargs:
            return True  # 没有需要更新的字段

        try:
            conn = self._get_connection()
            if not conn:
                log_error("无法获取数据库连接")
                return False
            cursor = conn.cursor()

            # 构建更新语句
            set_clause = ", ".join([f"{key} = ?" for key in kwargs.keys()])
            values = list(kwargs.values()) + [user_id, category]

            cursor.execute(f"UPDATE practice_progress SET {set_clause} WHERE user_id = ? AND category = ?", values)
            conn.commit()
            if cursor.rowcount > 0:
                log_debug(f"更新用户{user_id}分类{category}的练习进度成功")
                return True
            log_debug(f"未找到用户{user_id}分类{category}的练习进度，更新失败")
            return False
        except Exception as e:
            log_exception(f"更新练习进度失败: {str(e)}")
            return False
        finally:
            if conn:
                self.db_pool.release_connection(conn)

    def delete_by_user_and_category(self, user_id: int, category: str) -> bool:
        """
        根据用户ID和分类删除练习进度
        :param user_id: 用户ID
        :param category: 题目分类
        :return: 删除成功返回True，否则返回False
        """
        sql = "DELETE FROM practice_progress WHERE user_id = ? AND category = ?"
        params = (user_id, category)
        try:
            conn = self._get_connection()
            if not conn:
                log_error("无法获取数据库连接")
                return False
            cursor = conn.cursor()
            cursor.execute(sql, params)
            conn.commit()
            if cursor.rowcount > 0:
                log_debug(f"删除用户{user_id}分类{category}的练习进度成功")
                return True
            log_debug(f"未找到用户{user_id}分类{category}的练习进度，删除失败")
            return False
        except Exception as e:
            log_exception(f"删除练习进度失败: {str(e)}")
            return False
        finally:
            if conn:
                self.db_pool.release_connection(conn)